﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;

namespace UnionPay4WP
{
    public class MixDecoder
    {
        
        public MixDecoder()
        {
            midlen = 0;
            decodeTable['A'] = Convert.ToChar(0);
            decodeTable['B'] = Convert.ToChar(1);
            decodeTable['C'] = Convert.ToChar(2);
            decodeTable['D'] = Convert.ToChar(3);
            decodeTable['E'] = Convert.ToChar(4);
            decodeTable['F'] = Convert.ToChar(5);
            decodeTable['G'] = Convert.ToChar(6);
            decodeTable['H'] = Convert.ToChar(7);
            decodeTable['I'] = Convert.ToChar(8);
            decodeTable['J'] = Convert.ToChar(9);
            decodeTable['K'] = Convert.ToChar(10);
            decodeTable['L'] = Convert.ToChar(11);
            decodeTable['M'] = Convert.ToChar(12);
            decodeTable['N'] = Convert.ToChar(13);
            decodeTable['O'] = Convert.ToChar(14);
            decodeTable['P'] = Convert.ToChar(15);
            decodeTable['Q'] = Convert.ToChar(16);
            decodeTable['R'] = Convert.ToChar(17);
            decodeTable['S'] = Convert.ToChar(18);
            decodeTable['T'] = Convert.ToChar(19);
            decodeTable['U'] = Convert.ToChar(20);
            decodeTable['V'] = Convert.ToChar(21);
            decodeTable['W'] = Convert.ToChar(22);
            decodeTable['X'] = Convert.ToChar(23);
            decodeTable['Y'] = Convert.ToChar(24);
            decodeTable['Z'] = Convert.ToChar(25);
            decodeTable['a'] = Convert.ToChar(26);
            decodeTable['b'] = Convert.ToChar(27);
            decodeTable['c'] = Convert.ToChar(28);
            decodeTable['d'] = Convert.ToChar(29);
            decodeTable['e'] = Convert.ToChar(30);
            decodeTable['f'] = Convert.ToChar(31);
            decodeTable['g'] = Convert.ToChar(32);
            decodeTable['h'] = Convert.ToChar(33);
            decodeTable['i'] = Convert.ToChar(34);
            decodeTable['j'] = Convert.ToChar(35);
            decodeTable['k'] = Convert.ToChar(36);
            decodeTable['l'] = Convert.ToChar(37);
            decodeTable['m'] = Convert.ToChar(38);
            decodeTable['n'] = Convert.ToChar(39);
            decodeTable['o'] = Convert.ToChar(40);
            decodeTable['p'] = Convert.ToChar(41);
            decodeTable['q'] = Convert.ToChar(42);
            decodeTable['r'] = Convert.ToChar(43);
            decodeTable['s'] = Convert.ToChar(44);
            decodeTable['t'] = Convert.ToChar(45);
            decodeTable['u'] = Convert.ToChar(46);
            decodeTable['v'] = Convert.ToChar(47);
            decodeTable['w'] = Convert.ToChar(48);
            decodeTable['x'] = Convert.ToChar(49);
            decodeTable['y'] = Convert.ToChar(50);
            decodeTable['z'] = Convert.ToChar(51);
            decodeTable['0'] = Convert.ToChar(52);
            decodeTable['1'] = Convert.ToChar(53);
            decodeTable['2'] = Convert.ToChar(54);
            decodeTable['3'] = Convert.ToChar(55);
            decodeTable['4'] = Convert.ToChar(56);
            decodeTable['5'] = Convert.ToChar(57);
            decodeTable['6'] = Convert.ToChar(58);
            decodeTable['7'] = Convert.ToChar(59);
            decodeTable['8'] = Convert.ToChar(60);
            decodeTable['9'] = Convert.ToChar(61);
            decodeTable['+'] = Convert.ToChar(62);
            decodeTable['/'] = Convert.ToChar(63);
        }
        
        public string src { get; set; }
        public char[] mid { get; set; }
        public char[] dst { get; set; }

        private char[] decodeTable = new char[256];

        private int midlen;
        public int midLen { get { return midlen; }  }

        public void urlDecode()
        {
            mid = new char[src.Length+1];
            int i = 0, j = 0;
            for (; i < src.Length; )
            {
                if (src[i] >= 'a' && src[i] <= 'z' || src[i] >= 'A' && src[i] <= 'Z' || src[i] >= '0' && src[i] <= '9'|| src[i]=='/')
                {
                    mid[j++] = src[i++];
                }
                else if ('+' == src[i])
                    {
                        i++;
                        mid[j++] = ' ';
                    }
                else if ('%' == src[i])
                {
                    int temp = Convert.ToInt32(src.Substring(++i, 2), 16);
                    mid[j++] = Convert.ToChar(temp);
                    i += 2;
                }
                else {
                  // mid[j++] = src[i++];
                    i++;
                }
            
            }
            mid[j++] = '\0';
            midlen = j;
        }

        public void Base64Decode()
        {
            dst = new Char[midlen * 3 / 4 + 2];
            int i = 0, j = 0,end=5;
            bool flag = true;
            while (flag&&mid[i]!='\0')
            {
                for (int m = 0; m < 4; m++)
                {
                    if ('=' == mid[i+m])
                    {
                        end = m;
                        mid[i + m] = '\0';
                        flag=false;
                        break;
                    }
                    else
                    {
                        mid[i+m] = decodeTable[mid[i+m]];
                    }
                }

                dst[j++] = Convert.ToChar( (mid[i] & 0x3f) << 2 | (mid[i + 1] & 0x30) >> 4);
                dst[j++] = Convert.ToChar((mid[i + 1] & 0xf) << 4 | (mid[i + 2] & 0x3c) >> 2);
                dst[j++] = Convert.ToChar((mid[i + 2] & 0x3) << 6 | (mid[i + 3] & 0x3f)) ;
                i += 4;

            }
            if(!flag)
            {
                dst[j++] = Convert.ToChar( (mid[i] & 0x3f) << 2 | (mid[i + 1] & 0x30) >> 4);

                if(end==3)
                {
                    dst[j++] = Convert.ToChar((mid[i + 1] & 0xf) << 4 | (mid[i + 2] & 0x3c) >> 2);
                }
            }
           dst[j++] = '\0';
        }
    }
}
